package jp.co.systemi.asp.workflow.route;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import jp.co.systemi.asp.workflow.Main;
import jp.co.systemi.asp.workflow.data.ApproverMeta;
import jp.co.systemi.asp.workflow.data.Route;
import jp.co.systemi.asp.workflow.data.RouteMeta;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.authorization.strategies.role.Roles;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.PropertyModel;
import org.datanucleus.util.StringUtils;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.GlobalTransaction;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;

/**
 * 決裁ルート登録 Mainから継承すること
 *
 * @author wzhang
 *
 */
@AuthorizeInstantiation(Roles.ADMIN)
public class RouteReg extends Main {
    /**
     * ログ出力 クラス名をあわせること
     */
    private static final Logger log = Logger
            .getLogger(RouteReg.class.getName());
    private static final String UNIQE_KEY = "uniqueRouteName";
    List<Route> routes = new ArrayList<Route>();

    String routeName = "";

    /**
     * コンストラクター 画面の生成、イベント処理の定義はすべて、この中で完結する
     */
    public RouteReg() {
        init();
    }

    private void init() {
        // Formを生成する
        final Form<Route> form = new MainForm<Route>(this, "wi_routeRegForm");
        // データストアーから初期化する入力項目の生成は一番先に行う
        // ルート一覧を取得
        RouteMeta rm = RouteMeta.get();
        List<Route> orgRoutes = Datastore.query(rm).asList();
        for (int i = 0; i < orgRoutes.size(); i++) {
            Route route = orgRoutes.get(i);
            route.setSeq(i + 1);
            routes.add(route);
        }
        // ルートリスト
        final WebMarkupContainer tblRoute = new WebMarkupContainer(
                "wi_tblRoute");
        tblRoute.setOutputMarkupId(true);
        form.add(tblRoute);
        final TextField<String> wi_routeName = new TextField<String>(
                "wi_routeName", new PropertyModel<String>(this, "routeName"));
        wi_routeName.setOutputMarkupId(true);
        tblRoute.add(wi_routeName);
        tblRoute.add(new AjaxButton("wi_addRoute") {
            private static final long serialVersionUID = -2573012794536636414L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                if (StringUtils.isEmpty(routeName)) {
                    error(getString("routename.empty"));
                    target.addComponent(feedback);
                    return;
                }
                Transaction tx = Datastore.beginTransaction();
                // ユニック制御
                if (!Datastore.putUniqueValue(UNIQE_KEY, routeName)) {
                    error(getString("routename.exists"));
                    target.addComponent(feedback);
                    return;
                }

                Route route = new Route();
                route.setSeq(routes.size() + 1);
                route.setName(routeName);
                routes.add(route);
                Datastore.put(tx, route);
                Datastore.commit(tx);

                // メッセージをクリア
                target.addComponent(feedback);
                // テーブル再表示
                target.addComponent(tblRoute);
                // 入力をクリア
                routeName = "";
                target.addComponent(wi_routeName);
            }
        });
        tblRoute.add(new ListView<Route>("wi_trRoute", routes) {
            private static final long serialVersionUID = 4846361379394092695L;

            @Override
            protected void populateItem(ListItem<Route> item) {
                final Route route = item.getModelObject();
                item.add(new Label("wi_tdSeq", new PropertyModel<Integer>(
                        route, "seq")));
                PageParameters pars = new PageParameters();
                pars.add("routeId", Long.toString(route.getId().getId()));
                BookmarkablePageLink<RouteEdit> link = new BookmarkablePageLink<RouteEdit>(
                        "wi_tdRouteEditLink", RouteEdit.class, pars);
                item.add(link);
                link.add(new Label("wi_tdRouteName", new PropertyModel<String>(
                        route, "name")));
                item.add(new AjaxLink<Object>("wi_tdDelete") {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        log.info("delete");
                        GlobalTransaction gtx = Datastore.beginGlobalTransaction();
                        gtx.delete(route.getId());
                        // Unique名を削除
                        Datastore.deleteUniqueValue(UNIQE_KEY, route.getName());
                        ApproverMeta am = ApproverMeta.get();
                        List<Key> approverKeys = Datastore.query(am).filter(am.routeId.equal(route.getId())).asKeyList();
                        gtx.delete(approverKeys);
                        gtx.commit();
                        routes.remove(route);
                        // 紐付くルート情報も削除

                        // 順番を振りなおし
                        int i = 0;
                        for (Route r : routes) {
                            r.setSeq(++i);
                        }
                        target.addComponent(feedback);
                        target.addComponent(form);
                    }

                });
            }
        });
    }
}
